package com.me.libgdx_test;

import java.lang.reflect.InvocationTargetException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.Align;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.me.libgdx_test.ClassListComparator.ClassComparator;
import com.me.libgdx_test.ClassListComparator.SpellComparator;

public class ActivityMarketScreen implements Screen{
	
	ActivityMain game;
	Stage stage;
	SpriteBatch batch;
	ClassSkinReference skin;
	ClassLogDisplay logger;
	ClassMarketDirector market_director;
	Table switch_table;
	Point table_dims;
	ClassAchievementInfo achievement_bar;
	private int width, height, button_width, button_height;
	
	public ActivityMarketScreen(final ActivityMain game) throws NoSuchMethodException, SecurityException{
		this.game = game;
		logger = new ClassLogDisplay("ActivityMarketScreen");
		logger.print(String.valueOf(Gdx.graphics.getWidth()) + "x" + String.valueOf(Gdx.graphics.getHeight()));
		batch = new SpriteBatch();
		stage = new Stage();
		skin = game.skin;
		
		width = Gdx.graphics.getWidth();
		height = Gdx.graphics.getHeight();
		
		table_dims = new Point(width,height);
		logger.print(table_dims);
		
		button_width = 16*width/100;
		button_height = height/10;
		
		Gdx.input.setInputProcessor(stage);
		
		/*final Table table = new Table();
		table.setFillParent(true);
		stage.addActor(table);*/
	}

	public void init_stage_objects() throws NoSuchMethodException, SecurityException{
		Group hire_tabs = new Group();
		
		market_director = new ClassMarketDirector(stage, hire_tabs, table_dims, 
				new Point(table_dims.x/16,95*table_dims.y/100),game.unlockable, this, game);
		
		final Label title_label = new Label("Quest Market", skin.get_skin());
		//title_label.setPosition(width/8, 9*height/10);
		//title_label.setSize(width/10, height/10);
		title_label.setFontScale(10);
		title_label.setPosition(17*width/100, 17*height/20);
		stage.addActor(title_label);
		
		/*table.add(title_label).size(width/3,height/8).padBottom(height/15);
		table.row();
		table.row();*/
		
		final TextButton Back_Button = new TextButton("Back", skin.get_button_skin());
		Back_Button.setPosition(4*width/100, 6*height/10);
		Back_Button.setSize(button_width, button_height);
		//table.add(Tavern_Button).size(button_width,button_height).align(Align.left);
		Back_Button.addListener(new ChangeListener() {
			public void changed (ChangeEvent event, Actor actor) {
				game.setScreen(game.indexScreen);
			}
		});
		stage.addActor(Back_Button);
		
		final TextButton Tavern_Button = new TextButton("Tavern", skin.get_button_skin());
		Tavern_Button.setPosition(22*width/100, 6*height/10);
		Tavern_Button.setSize(button_width, button_height);
		//table.add(Tavern_Button).size(button_width,button_height).align(Align.left);
		Tavern_Button.addListener(new ChangeListener() {
			public void changed (ChangeEvent event, Actor actor) {
				try {
					set_test_items();
					market_director.set_tavern_options();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		stage.addActor(Tavern_Button);
		
		final TextButton Market_Button = new TextButton("Market", skin.get_button_skin());
		Market_Button.setPosition(40*width/100, 6*height/10);
		Market_Button.setSize(button_width, button_height);
		Market_Button.addListener(new ChangeListener() {
			public void changed (ChangeEvent event, Actor actor) {
				try {
					set_test_items();
					market_director.set_market_options();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		stage.addActor(Market_Button);
		
		final TextButton Inn_Button = new TextButton("Academy", skin.get_button_skin());
		Inn_Button.setPosition(58*width/100, 6*height/10);
		Inn_Button.setSize(button_width, button_height);
		Inn_Button.addListener(new ChangeListener() {
			public void changed (ChangeEvent event, Actor actor) {
				try {
					logger.print("Academy Button Pressed");
					set_test_items();
					market_director.set_inn_options();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		stage.addActor(Inn_Button);

		final TextButton Bank_Button = new TextButton("Bank", skin.get_button_skin());
		Bank_Button.setPosition(76*width/100, 6*height/10);
		Bank_Button.setSize(button_width, button_height);
		Bank_Button.addListener(new ChangeListener() {
			public void changed (ChangeEvent event, Actor actor) {
				try {
					logger.print("Bank Button Pressed");
					set_test_items();
					market_director.set_bank_options();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		stage.addActor(Bank_Button);
		
		//hire_tabs.setPosition(width/10, 5*height/10);
		//hire_tabs.setSize(4*width/5, 100);
		
		logger.print(new Point((int)hire_tabs.getX(),(int)hire_tabs.getY()));
		
		stage.addActor(hire_tabs);
		
		achievement_bar = new ClassAchievementInfo(game,table_dims);
		
		set_test_items();
		market_director.set_tavern_options();
	}
	
	public void add_achievement_bar(Stage stage){
		stage.addActor(achievement_bar.get_achievement_group());
	}
	
	public void set_test_items() throws NoSuchMethodException, SecurityException{
		
		long seed = System.nanoTime();
		
		ClassTexturePackerLoader sprite_textures = game.sprite_textures;
		ClassReferenceDrawable reference = new ClassReferenceDrawable(0,0,0,game.unlockable);
		
		logger.print("Reference Intialized: " + String.valueOf(reference.initialized));
		
		game.unlockable.get_unlockable_prototypes().get_factory().print_data();
		
		market_director.reset_options();
		//An array of the inaccessable player classes
		
		ArrayList<ClassDungeonPlayerClass> player_classes = new ArrayList<ClassDungeonPlayerClass>();
		for(int i = 0; i < reference.classObjects.length; i++){
			if(!reference.classObjects[i].unlocked && !market_director.value_in_tavern(i)){
				player_classes.add(reference.classObjects[i]);
			}
		}
		
		ClassListComparator list_comp = new ClassListComparator();
		ClassComparator class_comp = list_comp.new ClassComparator();
		
		Collections.sort(player_classes, class_comp);
		ArrayList<Integer> class_indexes = new ArrayList<Integer>();
		
		for(ClassDungeonPlayerClass player_class:player_classes){
			for(int i = 0; i < reference.classObjects.length; i++){
				if(reference.classObjects[i].equals(player_class)){
					class_indexes.add(i);
				}
			}
		}
		
		ArrayList<Integer> upgrade_indexes = new ArrayList<Integer>();
		for(int i = 0; i < reference.shopObjects.length; i++){
			if(reference.shopObjects[i].upgradeable && reference.shopObjects[i].tech_level<10 && !market_director.value_in_market(i)){
				upgrade_indexes.add(i);
			}
		}
		Collections.shuffle(upgrade_indexes, new Random(seed));
		
		SpellComparator spell_comp = list_comp.new SpellComparator();
		
		ArrayList<ClassDungeonSpell> player_spells = new ArrayList<ClassDungeonSpell>();
		for(int i = 0; i < reference.spellObjects.length; i++){
			if(!reference.spellObjects[i].unlocked && !market_director.value_in_inn(i)){
				player_spells.add(reference.spellObjects[i]);
			}
		}
		
		Collections.sort(player_spells, spell_comp);
		ArrayList<Integer> spell_indexes = new ArrayList<Integer>();
		
		for(ClassDungeonSpell player_spell:player_spells){
			for(int i = 0; i < reference.spellObjects.length; i++){
				if(reference.spellObjects[i].equals(player_spell)){
					spell_indexes.add(i);
				}
			}
		}

		/*ArrayList<Integer> spell_indexes = new ArrayList<Integer>();
		for(int i = 0; i < reference.spellObjects.length; i++){
			if(!reference.spellObjects[i].unlocked && !market_director.value_in_inn(i)){
				spell_indexes.add(i);
			}
		}
		Collections.shuffle(spell_indexes, new Random(seed));*/
		
		for(int i = market_director.get_tavern_size(); i < (class_indexes.size()>5?5:class_indexes.size()); i++){
			String item_title = reference.classObjects[class_indexes.get(i)].Name;
			String item_description = reference.classObjects[class_indexes.get(i)].Description;
			
			market_director.add_tavern_option(sprite_textures.find_by_name(reference.classObjects[class_indexes.get(i)].Image), 
					item_title, item_description, "Hire", class_indexes.get(i), 
					reference.classObjects[class_indexes.get(i)].unlock_cost);
		}
		for(int i = 0; i < market_director.get_market_size(); i++){
			int upgrade_index = market_director.get_market_list().get(i).get_click_index();
			
			String upgrade_string = reference.shopObjects[upgrade_index].Name + ": ";
			upgrade_string += reference.shopObjects[upgrade_index].get_level_description(reference.shopObjects[upgrade_index].tech_level,true);
			//logger.print("Upgrade String: " + upgrade_string);
			market_director.update_market_description(upgrade_string,i);
			
			ClassUnlockCost cost = reference.shopObjects[upgrade_index].get_unlock_cost();
			
			market_director.update_market_cost(cost, i);
		}
		for(int i = market_director.get_market_size(); i < (upgrade_indexes.size()>5?5:upgrade_indexes.size()); i++){
			
			String item_title = reference.shopObjects[upgrade_indexes.get(i)].Name;
			String item_description = reference.shopObjects[upgrade_indexes.get(i)].Description;
			
			market_director.add_market_option(sprite_textures.find_by_name(reference.shopObjects[upgrade_indexes.get(i)].Image), 
					item_title, item_description,
					"Upgrade",upgrade_indexes.get(i), reference.shopObjects[upgrade_indexes.get(i)].unlock_cost);
		}
		for(int i = market_director.get_inn_size(); i < (spell_indexes.size()>5?5:spell_indexes.size()); i++){
			String item_title = reference.spellObjects[spell_indexes.get(i)].Name;
			String item_description = reference.spellObjects[spell_indexes.get(i)].Description;
			
			market_director.add_inn_option(sprite_textures.find_by_name(reference.spellObjects[spell_indexes.get(i)].Image), 
					item_title, item_description, "Learn", spell_indexes.get(i), reference.spellObjects[spell_indexes.get(i)].unlock_cost);
		}
		for(int i = 0; i < reference.bank_objects.length; i++){
			String item_title = reference.bank_objects[i].Name;
			
			NumberFormat formatter = NumberFormat.getCurrencyInstance();
			
			String item_description = reference.bank_objects[i].Description + " (" + formatter.format(reference.bank_objects[i].get_price()) + ")";
			
			market_director.add_bank_option(sprite_textures.find_by_name(reference.bank_objects[i].Image), 
					item_title, item_description, "Apply", i, reference.bank_objects[i].unlock_cost);
		}
		achievement_bar.populate_achievement_object();
	}
	
	@Override
	public void render(float delta) {
		Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
		stage.draw();
		Table.drawDebug(stage);
	}

	@Override
	public void resize(int width, int height) {
		stage.setViewport(width, height, false);
	}

	@Override
	public void show() {
		try {
			Gdx.input.setInputProcessor(stage);
			logger.print("OnShow");
			stage.clear();
			init_stage_objects();
			add_achievement_bar(stage);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void hide() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
	}

	@Override
	public void dispose() {
		stage.dispose();
		//skin.get_skin().dispose();
	}
	
	public void item_purchased(int item_level, String purchase_code){
		logger.print("Item level: " + item_level); 
		logger.print("Item purchase code: " + purchase_code); 
		
		game.unlockable.get_unlockable_prototypes().get_factory().bank_loan(item_level);

		
		
		//game.reset_activities();
		game.unlockable.save_data_to_server();
		achievement_bar.refresh_achievement_group();
	}

}
